var SCOPED = (function() {
	// TODO: HTML5 shiv
	var html5 = "article,section,header,footer,hgroup,aside".split(",");
	for(var i in html5)
		document.createElement(html5[i]);
	
	var util = {
		addEvent: function(obj, type, fn) {
			if (obj.attachEvent) {
				obj['e'+type+fn] = fn;
				obj[type+fn] = function(){ obj['e'+type+fn](window.event); }
				obj.attachEvent('on'+type, obj[type+fn]);
			} else
				obj.addEventListener( type, fn, false );
		},
		removeEvent: function (obj, type, fn) {
			if (obj.detachEvent) {
				obj.detachEvent('on'+type, obj[type+fn]);
				obj[type+fn] = null;
			} else
			obj.removeEventListener(type, fn, false);
		},
		trim: function(v) {
			return v.toString().replace(/^\s*|\s*$/, "");
		},
		normalize: function(v) {
			return util.trim(v.toString().replace(/\s+/g, " "));
		}
	};
	
	var DOM = {
		byType: function(tagName, context) {
			if(typeof(context) !== 'undefined')
				return context.getElementsByTagName(tagName);
			return document.getElementsByTagName(tagName);
		},
		byId: function(id) {
			return document.getElementById(id);
		},
		create: function(html) {
			return document.createElement(html);
		},
		append: function(what, where) {
			where.appendChild(what);
			return what;
		},
		detach: function(what) {
			what.parentNode.removeChild(what);
			return what;
		},
		attr: function(what, which, value) {
			if(typeof(value) === "undefined")
				return what.attributes.getNamedItem(which);
			what.attributes.getNamedItem(which).value = value;
			return what;
		}
	};
	
	var settings = {
		useId: true,
		useClassName: true,
		useHierarchy: false
	};

	var init = function() {
		var styles = DOM.byType("style", document.body);
		var scoped = [];
		
		// iterate over all scoped styles and associate with container elements
		for(var i = 0; i < styles.length; i++) {
			if(DOM.attr(styles[i], "scoped")) {
				scoped.push({ parent: styles[i].parentNode, tag: styles[i]});
				DOM.detach(styles[i]);
			}
		}
		
		// process each scoped style tag and process rules according to settings
		var head = DOM.byType("head")[0];
		for(var j = 0; j < scoped.length; j++) {
			// remove comments and split rules using the '}' character
			var rules = util.normalize(scoped[j].tag.innerHTML).replace(/\/\*.*?\*\//g, "").split("}");
			var parent = scoped[j].parent;
			var t = [];
			// iterate over each rule
			for(var k = 0; k < rules.length; k++) {
				var split = rules[k].split("{");
				if(util.normalize(rules[k]) != "") {
					// walk up hierarchy and prepend the path
					var prefix = "";
					var current = parent;
					if(settings.useHierarchy) {
						while(current = current.parentNode) {
							var node = current.nodeName.toLowerCase(); 
							if(node === "html") break;
							prefix = node + ">" + prefix;
						}
					}
					t.push(
						prefix + parent.tagName.toLowerCase() +
						((util.normalize(parent.id) != "" && settings.useId)? "#" + util.normalize(parent.id): "") +
						((util.normalize(parent.className) != "" && settings.useClassName)? "." + util.normalize(parent.className).split(" ").join("."): "") +
						" " + util.normalize(split[0]) + "{" + split[1] + "}"
					);
				}
			}
			var style = DOM.create("style");
			style.setAttribute("type", "text/css");
			if(style.styleSheet) {
				// IE-style stylesheet assignment
				style.styleSheet.cssText = t.join("\n");
			} else {
				// other browsers
				style.appendChild(document.createTextNode(t.join("\n")));
			}
			DOM.append(style, head);
		}
	};
	
	// expose public settings
	return {
		init: init,
		util: util,
		settings: settings,
		onLoad: function() { util.addEvent(window, "load", init); }
	};
})();